home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
pctj486.arc
/
SETALARM.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-02-20
|
7KB
|
182 lines
;----------------------------------------------------------
; Set the PC/AT alarm to user-specified time. Points alarm
; vector to BEEPER procedure which remains resident.
;-----------------------------------------------------------
; (c) Copyright Leo J. Scanlon, 1986
.286c
PRINT$ MACRO STRING ; Macro that prints a string
LEA DX,STRING
MOV AH,9
INT 21H ;Function 9: display string
ENDM
PROGRAM SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:PROGRAM,DS:PROGRAM,ES:PROGRAM,SS:PROGRAM
ORG 100H ;designed as .COM file
BEGINING:
JMP MAIN ;jump around procs and data
START_RESIDENT:
BEEPER PROC
PUSHA ;Save the user's registers
MOV CX,5 ;Beep five times
BEEP: MOV AL,7 ;Beep for one second
MOV AH,0EH
INT 10H ;Video EH: write char as TTY
LOOP BEEP
POPA ;Restore the registers
IRET
BEEPER ENDP
END_RESIDENT:
RESIDENT_LENGTH EQU END_RESIDENT - START_RESIDENT
RESIDENT_OFFSET EQU START_RESIDENT - BEGINING + 100H
;----------------------------------------------------------------
; See if BEEPER proc is already resident. Sets FIRST_TIME?=0 if
; alarm vector 4AH points to beeper routine, else leaves it 1
;----------------------------------------------------------------
FIRST_TIME? DB 1
CHECK_BEEPER PROC
MOV AH, 35H
MOV AL, 4AH
INT 21H ;function 35H (get interrupt vector)
MOV DI,BX ; set up ES:DI
MOV SI,[RESIDENT_OFFSET] ; address BEEPER
; with DS:SI
MOV CX,[RESIDENT_LENGTH] ; set length for CMPS
REPE CMPSB
JZ ALREADY_THERE ; ZF set means match
RET
ALREADY_THERE: MOV FIRST_TIME?,0
RET
CHECK_BEEPER ENDP
;------------------------------------------------------
; data area: messages, prompts, and keystroke buffer.
;------------------------------------------------------
CRLF DB 13,10,'$'
BAD_DATA DB 'Digits must be between 0 and 9',13,10,'$'
BAD_HRS DB 'Hours must be between 0 and 23',13,10,'$'
BAD_MINS DB 'Minutes must be between 0 and 59',13,10,'$'
BAD_SECS DB 'Seconds must be between 0 and 59',13,10,'$'
PROMPT DB 'Set the alarm time.',13,10
DB 'Enter values or press Enter for zero'
DB 13,10,'$'
ASK_HRS DB 'Hour (0-23): $'
ASK_MINS DB 'Minute (0-59): $'
ASK_SECS DB 'Second (0-59): $'
USER$ DB 3,4 DUP(?)
; User's response in 5 byte buffer
; <length of buffer> <chars read> <char1> <char2> <ret>
;---------------------------------------------------------------
; GET_TIME reads up to two keys into string buffer USER$,
; then converts them into a packed BCD number in BL.
; If either key is invalid, it prints an error message and sets
; CF to 1.
;---------------------------------------------------------------
GET_TIME PROC
LEA DX,USER$ ;Read user's response
MOV AH,0AH
INT 21H ; function AH (get keyboard input)
stop1: PRINT$ CRLF ;Advance to next line
CMP USER$+1,1 ;Check key count
JAE CONVERT
SUB BL,BL ;User pressed Enter
RET
CONVERT: MOV AL,USER$+2 ;Get first key
CALL CHECK ;Check this character
JC LEAVE ;If it is valid,
AND AL,0FH ; convert it to BCD
MOV BL,AL
CMP USER$+1,2 ;Is there another key?
JB CLR_CF
SHL BL,4 ;Yes. Put first digit in high bits
MOV AL,USER$+3 ;Get second key
CALL CHECK ;Check this character
JC LEAVE ;If it is valid,
AND AL,0FH ; convert it to BCD
OR BL,AL
CLR_CF: CLC
LEAVE: RET
GET_TIME ENDP
;-----------------------------------------------------------
; CHECK makes sure an entry value is between 0 and
; 9. If not, it displays an error message and sets CF to 1.
;-----------------------------------------------------------
CHECK PROC
CMP AL,'0' ;If entry is < 0
JB ERROR
CMP AL,'9' ; or > 9,
JA ERROR ; print message
CLC ;Otherwise, clear CF and return
RET
ERROR: PRINT$ BAD_DATA ;Display error message
STC ;Set CF and return
RET
CHECK ENDP
MAIN PROC NEAR
MOV AH,7 ;Reset the alarm
INT 1AH ; AT BIOS interrupt 1AH (reset alarm)
CALL CHECK_BEEPER
CMP FIRST_TIME?, 1
JNE USER_INPUT
MOV AL,4AH ;Make the 4A vector point to BEEPER
LEA DX,BEEPER
MOV AH,25H
INT 21H ;function 25H (set interrupt vector)
USER_INPUT:
PRINT$ PROMPT ;Ask for alarm hour
HOUR: PRINT$ ASK_HRS
CALL GET_TIME ;Convert it to BCD
JC HOUR
CMP BL,23H ;Make sure it's < 24
JNA HRS2CH
PRINT$ BAD_HRS
JMP HOUR
HRS2CH: MOV CH,BL ; and put it in CH
MIN: PRINT$ ASK_MINS ;Ask for alarm minutes
CALL GET_TIME ;Convert it to BCD
JC MIN
CMP BL,59H ;Make sure it's < 60
JNA MIN2CL
PRINT$ BAD_MINS
JMP MIN
MIN2CL: MOV CL,BL ; and put it in CL
SEC: PRINT$ ASK_SECS ;Ask for alarm seconds
CALL GET_TIME ;Convert it to BCD
JC SEC
CMP BL,59H ;Make sure it's < 60
JNA SEC2DH
PRINT$ BAD_SECS
JMP SEC
SEC2DH: MOV DH,BL ; and put it in DH
MOV AH,6
INT 1AH ;AT BIOS interrupt 1AH (set alarm)
CMP FIRST_TIME?, 1
JNE CLEAR_OUT
MOV DX, RESIDENT_OFFSET + RESIDENT_LENGTH
;first invocation - leave BEEPER resident
INT 27H ;interrupt 27H (terminate, stay resident)
CLEAR_OUT:
RET ;BEEPER already in place so
;exit normally
MAIN ENDP
PROGRAM ENDS
END BEGINING